/**
 * Copyright © 2011 Creativor Studio.
 * About license information, please see LICENSE.txt.
 */

package org.creativor.rayson.server;

import org.creativor.rayson.api.Session;

/**
 * The context of the RPC reqeust.
 * 
 * @author Nick Zhang
 */
public final class RpcRequestContext
{
	
	private ThreadLocal<Session> tlSession;
	
	private RpcRequestContext()
	{
		tlSession = new ThreadLocal<Session>();
	}
	
	private static RpcRequestContext context = new RpcRequestContext();
	
	/**
	 * Get session information of the RPC context.
	 * 
	 * @throws IllegalStateException
	 *             If the current thread is in handling RPC request. Or if can
	 *             not find session in current local thread.
	 */
	public static Session getSession() throws IllegalStateException
	{
		return context.getSession1();
	}
	
	/**
	 * @return
	 */
	private Session getSession1()
	{
		checkThread();
		Session session = tlSession.get();
		if (session == null) throw new IllegalStateException("Can not find current RPC session");
		return session;
	}
	
	/**
	 * Set current request context session.
	 * 
	 * @param session
	 *            Session object to be set.
	 * @throws IllegalStateException
	 *             If the current thread is in handling RPC request..
	 */
	static void setSession(Session session) throws IllegalStateException
	{
		context.setSession1(session);
	}
	
	/**
	 * Abandon the session information of current request context.
	 */
	static void abandonSession()
	{
		context.abandonSession1();
	}
	
	/**
	 * 
	 */
	private void abandonSession1()
	{
		tlSession.remove();
	}
	
	private void setSession1(Session session)
	{
		if (session == null) throw new NullPointerException("Session should not be null");
		checkThread();
		tlSession.set(session);
	}
	
	/**
	 * 
	 */
	private static void checkThread()
	{
		if (!RpcServer.inHandlingRequest())
			throw new IllegalThreadStateException("Current thread is not in handling RPC request ");
	}
}
